package com.example.app.domain.repository;

import com.example.app.domain.entity.InputElement;
import com.example.app.domain.entity.OutputElement;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Repository
@Slf4j
public class ElementRepository {
    private static final int QUEUE_SIZE = 10;
    private static ArrayBlockingQueue<InputElement> sourceData = new ArrayBlockingQueue<>(QUEUE_SIZE);
    private static ArrayBlockingQueue<OutputElement> outputData = new ArrayBlockingQueue<>(QUEUE_SIZE);
    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
    Random random = new Random(100);


    public Queue<InputElement> getAllSourceData() {
        return sourceData;
    }

    public Queue<OutputElement> getAllOutputData() {
        return outputData;
    }

    private void generateData() {
        if (sourceData.size() >= QUEUE_SIZE) {
            sourceData.remove();
        }
        sourceData.add(new InputElement(random.nextInt(100), random.nextInt(100)));
    }

    private void calculateData() {
        InputElement e = sourceData.peek();
        if (outputData.size() >= QUEUE_SIZE) {
            outputData.remove();
        }
        assert e != null;
        outputData.add(new OutputElement(e.getX(), e.getY(), (long) e.getX() + e.getY(), e.getDate()));
    }

    @PostConstruct
    private void init() {
        executorService.scheduleAtFixedRate(this::generateData, 5, 2, TimeUnit.SECONDS);
        executorService.scheduleAtFixedRate(this::calculateData, 10, 2, TimeUnit.SECONDS);
    }
}
